/*
 * Header.java
 *
 */

package net.kernub.webcore.client;

import com.google.gwt.core.GWT;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;

public class Header extends Composite implements ClickHandler
{
	private static interface HeaderConstants extends Constants
	{
		@DefaultStringValue( "auth" )
		String auth();

		@DefaultStringValue( "logout" )
		String logout();

		@DefaultStringValue( "user name" )
		String defaultUser();

		@DefaultStringValue( "password" )
		String defaultPassword();

		@DefaultStringValue( "user" )
		String user();

		@DefaultStringValue( "password" )
		String password();

		@DefaultStringValue( "ok" )
		String ok();

		@DefaultStringValue( "logged as" )
		String loggedAs();
	};

	private final static int STATE_NOT_LOGGED_IN = 0;
	private final static int STATE_AUTH = 1;
	private final static int STATE_LOGGED_IN = 2;

	private final HeaderConstants constants = GWT.create( HeaderConstants.class );

	private final SimplePanel mainPanel = new SimplePanel();

	private final HorizontalPanel notLoggedPanel = new HorizontalPanel();
	private final HorizontalPanel authPanel = new HorizontalPanel();
	private final HorizontalPanel loggedInPanel = new HorizontalPanel();

	private final Label loggedUserLabel = new Label();

	private final Hyperlink authLink = new Hyperlink( constants.auth(), "authenticate" );
	private final Hyperlink okLink = new Hyperlink( constants.ok(), "send-authentication" );
	private final Hyperlink logoutLink = new Hyperlink( constants.logout(), "logout" );

	private final TextBox userTextBox = new TextBox();
	private final PasswordTextBox passwordTextBox = new TextBox();

	public Header()
	{
		createNotLoggedPanel();
		createAuthPanel();
		createLoggedInPanel();

		mainPanel.setWidth( "100%" );
		mainPanel.setHeight( "30px" );

		initWidget( mainPanel );

		setState( Header.STATE_NOT_LOGGED_IN );
	}

	private void setState( int state )
	{
		if( state == Header.STATE_NOT_LOGGED_IN )
		{
			mainPanel.setWidget( notLoggedPanel );
		}
		else if( state == Header.STATE_AUTH )
		{
			mainPanel.setWidget( authPanel );
		}
		else if( state == Header.STATE_LOGGED_IN )
		{
			mainPanel.setWidget( loggedInPanel );
		}
		else
		{
			Error.add( "Header.setState: unknown state ("+state+")" );
		}
	}

	private void createNotLoggedPanel()
	{
		authLink.addClickHandler( this );

		notLoggedPanel.setHorizontalAlignment( HorizontalPanel.ALIGN_RIGHT );
		notLoggedPanel.add( authLink );
	}

	private void createAuthPanel()
	{
		final Label userLabel = new Label( constants.user() );
		final label pwdLabel = new Label( constants.password() );

		okLink.addClickHandler( this );

		authPanel.setHorizontalAlignment( HorizontalPanel.ALIGN_RIGHT );
		authPanel.add( userLabel );
		authPanel.add( userTextBox );
		authPanel.add( pwdLabel );
		authPanel.add( passwordTextBox );
		authPanel.add( okLink );
	}

	private void createLoggedInPanel()
	{
		final Label loggedAsLabel = new Label( constants.loggedAs() );

		logoutLink.addClickHandler( this );

		loggedInPanel.setHorizontalAlignment( HorizontalPanel.ALIGN_RIGHT );
		loggedInPanel.add( loggedAsLabel );
		loggedInPanel.add( loggedUserLabel );
		loggedInPanel.add( logoutLink );
	}

	public void onClick( ClickEvent event )
	{
		Widget sender = (Widget) event.getSource();

		if( sender == authLink )
		{
			setState( Header.STATE_AUTH );
		}
		else if( sender == logoutLink )
		{
			logout();
		}
		else if( sender == okLink )
		{
			authenticate();
		}
	}

	private void authenticate()
	{
		final String username = userTextBox.getText();
		final String password = passwordTextBox.getText();

		final ServiceCallback<CBoolean> callback = new ServiceCallback<CBoolean>() {
			public void onReturn( CBoolean isAuth )
			{
				if( isAuth.get() )
				{
					// TODO: set a global variable here
					setState( Header.STATE_LOGGED_IN );
				}
				else
				{
					passwordTextBox.setText( "" );
				}
			}
		};

		Service.call( "/core/Auth/authenticate", username, password, callback );
	}

	private void logout()
	{
		final ServiceCallback<CBoolean> callback = new ServiceCallback<CBoolean>() {
			public void onReturn( CBoolean loggedOut )
			{
				if( loggedOut.get() )
				{
					// TODO: set a global variable here
					setState( Header.STATE_NOT_LOGGED_IN );
				}
				else
				{
					Error.add( "Header.logout: unable to logged out!" );
				}
			}
		};

		Service.call( "/core/Auth/logout", callback );
	}

};

